<?php

namespace App\Library\Service\Payment;

use App\Library\Logic\AddressLogic;
use App\Library\Logic\PaymentLogic;
use App\Library\Logic\PaymentRelatedLogic;
use App\Library\Logic\ShopOrderGoodsLogic;
use App\Library\Logic\ShopOrderLogic;
use App\Library\Service\AuctionOrderService;
use App\Library\Service\BaseService;
use App\Library\Service\WxMessageService;
use Exception;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Database\Eloquent\Model;
use Yansongda\Artful\Rocket;
use Yansongda\Supports\Collection;

class PaymentService extends BaseService
{
    /**
     * @param string $serialNumber
     * @param Collection|Rocket $result
     * @param Collection|Rocket $find
     * @return void
     */
    public static function paySuccess(string $serialNumber, Collection|Rocket $result, Collection|Rocket $find): void
    {
        $attach = $result->get('resource.ciphertext.attach');
        $orm = lineToHump($attach);
        $paymentRelated = PaymentRelatedLogic::findBySerialNumber($serialNumber);
        if (is_null($paymentRelated)) return;
        else if (is_null($paymentRelated->$orm)) return;
        else if (!is_null($paymentRelated->payment)) return;
        if (PaymentRelatedLogic::paySuccess($paymentRelated->id) === 0) return;
        try {
            $payment = PaymentLogic::insertForModel(self::paymentArray($paymentRelated, $result, $find));
            $className = '\App\Library\Logic\\' . ucfirst($orm) . 'Logic';
            $orderLogic = new $className;
            if (!$orderLogic::paySuccess($paymentRelated->object_id, $payment->pay_at)) {
                payLog(__CLASS__ . __FUNCTION__ . ':statusPayOk:' . $paymentRelated->id);
            }
            if ($orm === 'shopOrder') {
                mq('productOrderSplit', $paymentRelated->shopOrder);
                $orderInfo = ShopOrderLogic::query()->where([
                    'order_id' => $paymentRelated->object_id,
                ])->first();
                if (!empty($orderInfo)) {
                    $goodsData = [
                        'product_name' => ShopOrderGoodsLogic::query()
                            ->where([
                                'order_id' => $orderInfo->order_id,
                            ])->value('title'),
                        'name' => $orderInfo->order_contacts,
                        'mobile' => $orderInfo->order_contacts_mobile,
                        'address' => $orderInfo->order_contacts_address,
                        'time' => now()->toDateTimeString()
                    ];
                    WxMessageService::goodsWxMess($goodsData, [], [], 1);
                }
            } else if ($orm === 'auctionOrder') {
                $service = new AuctionOrderService;
                $service->refundBail($paymentRelated->object_id);
            }
        } catch (Exception $e) {
            payLog($e->getMessage());
        }
    }

    /**
     * @param Model $paymentRelated
     * @param Collection|Rocket $result
     * @param Collection|Rocket $find
     * @return array
     */
    protected static function paymentArray(Model $paymentRelated, Collection|Rocket $result, Collection|Rocket $find): array
    {
        if ($paymentRelated->payment_method_id === 1) {
            $amount = $result->get('total_amount');
            $payAt = $result->get('gmt_payment');
            $initiatorUserAccountId = $find->get('buyer_logon_id') . ':' . $result->get('buyer_id');
            $receiveUserAccountId = $result->get('seller_id');
            $outTradeNo = $result->trade_no;
            $orm = 'auctionOrder';
        } else {
            $amount = bcdiv($result->get('resource.ciphertext.amount.total'), 100, 2);
            $payAt = $result->get('resource.ciphertext.success_time');
            $initiatorUserAccountId = $result->get('resource.ciphertext.payer.openid');
            $receiveUserAccountId = $result->get('resource.ciphertext.mchid');
            $outTradeNo = $result->get('resource.ciphertext.transaction_id');
            $orm = lineToHump($result->get('resource.ciphertext.attach'));
        }
        if ($orm === 'shopOrder') $buyId = $paymentRelated->$orm->buy_user_id;
        else $buyId = $paymentRelated->$orm->user_id;
        return [
            'objectType' => $paymentRelated->object_type,
            'objectId' => $paymentRelated->object_id,
            'paymentRelatedId' => $paymentRelated->id,
            'amount' => $amount,
            'paymentMethodId' => $paymentRelated->payment_method_id,
            'initiatorUserId' => $buyId,
            'receiveUserId' => 0,
            'payAt' => $payAt,
            'initiatorUserAccountId' => $initiatorUserAccountId,
            'receiveUserAccountId' => $receiveUserAccountId,
            'outTradeNo' => $outTradeNo,
            'result' => $result,
            'find' => $find,
        ];
    }
}
